home *** CD-ROM | disk | FTP | other *** search
- S 2
-
-
- Type P to Pause, S to Stop listing
-
- cat puppy.c
- # include <stdio.h>
-
- long hash();
-
- main()
- {
- char cmd[16], key[1024], content[1024], fname[100], *bptr;
- int filedesc, mode, size, keysize, contsize, depth;
- long offset;
-
- while (1) {
- printf("? ");
- gets(cmd);
- switch (cmd[0]) {
- case '?':
- printf("create open klose read write find delete seq hash\n");
- break;
- case 'c':
- printf("Name? ");
- gets(fname);
- printf("Mode? ");
- scanf("%d", &mode);
- getchar();
- printf("Size? ");
- scanf("%d", &size);
- getchar();
- filedesc = hcreate(fname, mode, size);
- if (filedesc == -1) printf("Failed\n");
- else printf("Filedesc = %d\n", filedesc);
- break;
- case 'o':
- printf("Name? ");
- gets(fname);
- printf("Mode? ");
- scanf("%d", &mode);
- getchar();
- filedesc = hopen(fname, mode);
- if (filedesc == -1) printf("Failed\n");
- else printf("Filedesc = %d\n", filedesc);
- break;
- case 'k':
- printf("Filedesc? ");
- scanf("%d", &filedesc);
- getchar();
- filedesc = hclose(filedesc);
- if (filedesc == -1) printf("Failed\n");
- break;
- case 'r':
- printf("Filedesc? ");
- scanf("%d", &filedesc);
- getchar();
- printf("Key? ");
- gets(key);
- keysize = strlen(key);
- contsize = sizeof(content);
- bptr = content;
- contsize = hread(filedesc, key, keysize, content, contsize);
- if (contsize == -1) printf("Failed");
- else if (contsize > sizeof(content)) printf("Too big");
- else while (contsize--) putchar(*bptr++);
- putchar('\n');
- break;
- case 'w':
- printf("Filedesc? ");
- scanf("%d", &filedesc);
- getchar();
- printf("Key? ");
- gets(key);
- keysize = strlen(key);
- printf("Content? ");
- gets(content);
- contsize = strlen(content);
- contsize = hwrite(filedesc, key, keysize, content, contsize);
- if (contsize == -1) printf("Failed\n");
- break;
- case 'd':
- printf("Filedesc? ");
- scanf("%d", &filedesc);
- getchar();
- printf("Key? ");
- gets(key);
- keysize = strlen(key);
- contsize = hdelete(filedesc, key, keysize);
- if (contsize == -1) printf("Failed\n");
- break;
- case 'f':
- printf("Filedesc? ");
- scanf("%d", &filedesc);
- getchar();
- printf("Key? ");
- gets(key);
- keysize = strlen(key);
- contsize = hfind(filedesc, key, keysize, &bptr);
- if (contsize == -1) printf("Failed");
- else while (contsize--) putchar(*bptr++);
- putchar('\n');
- break;
- case 's':
- printf("Filedesc? ");
- scanf("%d", &filedesc);
- getchar();
- printf("Offset(hex)? ");
- scanf("%X", &offset);
- getchar();
- keysize = hseq(filedesc, &bptr, &offset);
- if (keysize == -1) printf("Failed\n");
- else {
- printf("New offset = %x\n", offset);
- while (keysize--) putchar(*bptr++);
- putchar('\n');
- }
- break;
- case 'h':
- printf("Key? ");
- gets(key);
- printf("Depth? ");
- scanf("%d", &depth);
- getchar();
- printf("Hash(hex) = %X\n", hash(key, strlen(key), depth));
- break;
- default:
- printf("Enter ? for help\n");
- break;
- }
- }
- }
- % cap off
- cap:
- Command not found.
- %
- Type Selection or M for list,
- P to set protocol, <CR> to exit:
- 1
-
-
- Type P to Pause, S to Stop listing
-
- cat hashf.c
- /* H A S H F L I B R A R Y
-
- Accesses data using (key,content) pairs stored in external files.
- Copyright 1985 John Cowan; all rights reserved.
- Permission granted for reproduction in non-commercial uses.
-
- This version has the following data-type dependencies:
- Long must be 4 characters long (32 bits).
- Short must be 2 characters long (16 bits).
- Int may be either.
- Key and buffer sizes are limited by the size of Short.
- File sizes (in bytes) are limited by the size of Long.
- */
-
- # define FDS 20 /* max number of open files system allows */
- static int fd;
-
- static struct { /* all disk stuff is long for portability */
- long _magic; /* magic number on disk, open flag in core */
- long _freeblk; /* pointer to available free block */
- long _bsize; /* block size of .dat file */
- long _cur; /* currently resident .dat block, -1 on disk */
- long _len; /* length of .dat file */
- long _depth; /* depth of .idx file */
- /* Remaining stuff is meaningless on disk */
- int _idxfd; /* fd of .idx file */
- char *_block; /* .dat block buffer */
- }
- _header[FDS];
-
- # define Header _header[fd]
- # define Magic Header._magic
- # define Bsize Header._bsize
- # define Freeblk Header._freeblk
- # define Cur Header._cur
- # define Idxfd Header._idxfd
- # define Block Header._block
- # define Len Header._len
- # define Depth Header._depth
-
- # define DEFAULT 10 /* default to 1024-byte .dat block size */
- # define SETFD \
- if (fd = ufd, fd < 0 || fd >= FDS || Magic != DATmagic) \
- return(-1)
- # define DATmagic 6460 /* "DAT" in RAD50 */
- # define BUFFER(x) (char *)(&x)
- # define NONNULL(x) if ((x) == 0) return(-1);
-
- # define GETVAL(p) (_t_ = *(p) , _t_+((p)[1]<<8))
- # define PUTVAL(p,i) (*(p) = i&0xFF , (p)[1] = i>>8)
- static int _t_;
-
- # define WALK(b,k,ks,c,cs) \
- (ks=GETVAL(b), b+=2, k=b, b+=ks, cs=GETVAL(b), b+=2, c=b, b+=cs)
-
- char *strcpy(), *strcat(), *malloc();
- long lseek(), hash(), balloc(), getidx();
-
- int hcreate(fname, mode, size)
- char *fname;
- int mode;
- int size;
- {
- char lname[100];
-
- strcpy(lname, fname);
- if (strlen(fname) > sizeof(lname)) return(-1);
- strcat(lname, ".idx");
- fd = creat(lname, mode);
- if (size == 0) size = DEFAULT;
- if (size < 7) size = 7;
- if (size > 15) return(-1);
- Bsize = 1<<size;
- write(fd, BUFFER(Bsize), 4);
- close(fd);
- strcpy(lname, fname);
- strcat(lname, ".dat");
- fd = creat(lname, mode);
- Magic = DATmagic;
- Freeblk = 0;
- Len = Bsize;
- Depth = 0;
- balloc(); /* also writes out header */
- close(fd);
- Magic = 0;
- return(hopen(fname, 2));
- }
-
- int hopen(fname, mode)
- char *fname;
- int mode;
- {
- # define OPENFAIL {hclose(fd); return(-1);}
- char lname[100];
- extern char *malloc();
-
- if (strlen(fname) > sizeof(lname)) return(-1);
- strcpy(lname, fname);
- strcat(lname, ".dat");
- fd = open(lname, mode);
- read(fd, BUFFER(Header), sizeof(Header));
- if (Magic != DATmagic) OPENFAIL
- strcpy(lname, fname);
- strcat(lname, ".idx");
- Idxfd = open(lname, mode);
- if (Idxfd == -1) OPENFAIL
-
- Cur = -1;
- Block = malloc((unsigned)Bsize);
- if (Block == 0) OPENFAIL
- return(fd);
- }
-
- hclose(ufd)
- int ufd;
- {
- SETFD;
- close(fd);
- close(Idxfd);
- if (Block) free(Block);
- Magic = 0;
- return(0);
- }
-
- int hread(ufd, key, keysize, buff, buffsize)
- int ufd;
- char *key;
- int keysize;
- char *buff;
- int buffsize;
- {
- char *content;
- int contsize;
- register i;
-
- contsize = hfind(ufd, key, keysize, &content);
- if (contsize > 0)
- for (i=0; i < buffsize && i < contsize; i++)
- buff[i] = content[i];
- return (contsize);
- }
-
- int hfind(ufd, key, keysize, pcontent)
- int ufd;
- char *key;
- int keysize;
- char **pcontent;
- {
- int contsize;
-
- SETFD;
- NONNULL(keysize);
- load(getidx(hash(key, keysize, (int)Depth)));
- contsize = search(key, keysize, pcontent);
- return(contsize);
- }
-
- int hdelete(ufd, key, keysize)
- int ufd;
- char *key;
- int keysize;
- {
- char *content;
-
- SETFD;
- NONNULL(keysize);
- load(getidx(hash(key, keysize, (int)Depth)));
- if (search(key, keysize, &content) == -1) return(-1);
- zap();
- return(rewrite());
- }
-
- int hwrite(ufd, key, keysize, buff, buffsize)
- int ufd;
- char *key;
- int keysize;
- char *buff;
- int buffsize;
- {
- char *content;
-
- SETFD;
- NONNULL(keysize);
- NONNULL(buffsize);
- if (keysize + buffsize + 7 > Bsize) return(-1);
- while (1) {
- load(getidx(hash(key, keysize, (int)Depth)));
- if (search(key, keysize, &content) != -1) zap();
- if (jam(Block, key, keysize, buff, buffsize) != -1) {
- return(rewrite());
- }
- split();
- }
- }
-
- int hseq(ufd, pkey, poffset)
- int ufd;
- char **pkey;
- long *poffset;
- # define Offset *poffset
- {
- long himask = ~(Bsize - 1);
- long lomask = Bsize - 1;
- char *blk;
- char *dummy;
- int keysize, dummysize;
-
- SETFD;
- if (Offset == 0) Offset = Bsize;
- blk = Block + (Offset & lomask);
- Offset &= himask;
- if(load(Offset) == -1) return(-1);
- WALK(blk, (*pkey), keysize, dummy, dummysize);
- Offset += GETVAL(blk) ? blk - Block : Bsize;
- return (keysize);
- }
-
- # define KNUTH 1327217885
-
- static unsigned long rotate(i)
- unsigned long i;
- {
- int bit;
-
- bit = (i & 0x80000000);
- if (bit) i &= 0x7FFFFFFF;
- return((i << 1) + bit);
- }
-
- long hash(s, len, depth)
- char *s;
- int len;
- int depth;
- {
- unsigned long accum = 0;
- long item = 0;
- int shift = 0;
- int i;
-
- for (i=0; i<len; i++) {
- item = (item<<6) + s[i];
- if (++shift == 5) {
- accum = rotate(accum) ^ item;
- item = shift = 0;
- }
- }
- if (shift) accum = rotate(accum) ^ item;
-
- accum *= KNUTH;
- accum = accum >> (32 - depth);
- return (accum);
- }
-
-
- static load(offset)
- long offset;
- {
- if (Cur != offset) {
- Cur = offset;
- lseek(fd, Cur, 0);
- if (read(fd, Block, (int)Bsize) == 0) return(-1);
- }
- return(0);
- }
-
- static int rewrite()
- {
- lseek(fd, Cur, 0);
- return((write(fd, Block, (int)Bsize) == -1) ? -1 : 0);
- }
-
- static long balloc()
- {
- long newblk;
- long zero = 0L;
-
- newblk = Len;
- Len += Bsize;
- lseek(fd, Len-4, 0);
- write(fd, BUFFER(zero), 4);
- lseek(fd, newblk, 0);
- write(fd, BUFFER(zero), 4);
- lseek(fd, 0L, 0);
- write(fd, BUFFER(Header), sizeof(Header));
- return(newblk);
- }
-
- static char *zapmark;
-
- static int same(dst, dlen, src, slen)
- char *dst, *src;
- int dlen, slen;
- {
- if (dlen != slen) return(0);
- while (dlen--)
- if (*dst++ != *src++) return(0);
- return(1);
- }
-
- static int search(key, keysize, pcontent)
- char *key;
- int keysize;
- char **pcontent;
- {
- char *blk = Block;
- char *bkey, *cont;
- int bkeysize, contsize;
-
- while (GETVAL(blk)) {
- zapmark = blk;
- WALK(blk, bkey, bkeysize, cont, contsize);
- if (same(key, keysize, bkey, bkeysize)) {
- *pcontent = cont;
- return (contsize);
- }
- }
- return(-1);
- }
-
- static int zap()
- {
- char *zapsrc = zapmark;
- char *key, *cont;
- int size, keysize, contsize;
-
- WALK(zapsrc, key, keysize, cont, contsize);
- while (size = GETVAL(zapsrc)) {
- PUTVAL(zapmark, size);
- zapsrc += 2;
- zapmark += 2;
- while (size--) *zapmark++ = *zapsrc++;
- }
- PUTVAL(zapmark, 0);
- return(GETVAL(Block) == 0);
- }
-
- static int jam(blk, key, keysize, buff, buffsize)
- char *blk, *key, *buff;
- int keysize, buffsize;
- {
- int size;
- char *blk0;
-
- blk0 = blk;
- while (size = GETVAL(blk)) blk += size + 2;
- if ((blk - blk0) + keysize + buffsize + 7 > Bsize) return(-1);
- /* 2 length words, zero word, r-byte at end of block */
- PUTVAL(blk, keysize);
- blk += 2;
- while (keysize--) *blk++ = *key++;
- PUTVAL(blk, buffsize);
- blk += 2;
- while (buffsize--) *blk++ = *buff++;
- PUTVAL(blk, 0);
- return(0);
- }
-
- static long getidx(offset)
- long offset;
- {
- lseek(Idxfd, offset, 0);
- read(Idxfd, BUFFER(offset), 4);
- return(offset);
- }
-
- # define R Block[Bsize-1]
- # define R0 new0[Bsize-1]
- # define R1 new1[Bsize-1]
-
- static split()
- {
- char *new0, *new1;
- long mask, hval, start, finish, i, newblk;
- char *blk = Block;
- int keysize, contsize;
- char *key, *content;
-
- if (R == Depth) expand();
- new0 = malloc((unsigned)Bsize);
- PUTVAL(new0, 0);
- new1 = malloc((unsigned)Bsize);
- PUTVAL(new1, 0);
- mask = 1 << (Depth - ++R);
- while (GETVAL(blk)) {
- WALK(blk, key, keysize, content, contsize);
- hval = hash(key, keysize, (int)Depth);
- if (hval & mask)
- jam(new1, key, keysize, content, contsize);
- else
- jam(new0, key, keysize, content, contsize);
- }
- R0 = R1 = R;
- lseek(fd, Cur, 0);
- write(fd, new0, (int)Bsize);
- newblk = balloc();
- lseek(fd, newblk, 0);
- write(fd, new1, (int)Bsize);
- Cur = -1;
- start = (hval & ~(mask - 1)) | mask;
- finish = start + mask;
- for (i = start; i < finish; i++) {
- lseek(Idxfd, i*4, 0);
- write(Idxfd, BUFFER(newblk), 4);
- }
- }
-
- static expand()
- {
- int idxlen = 1<<Depth;
- long entry[2];
- long register i;
-
- for (i=idxlen-1; i>=0; i--) {
- lseek(Idxfd, i*4, 0);
- read(Idxfd, BUFFER(entry[0]), 4);
- entry[1] = entry[0];
- lseek(Idxfd, i*8, 0);
- write(Idxfd, BUFFER(entry[0]), 8);
- }
- Depth++;
- }
- %
- Type Selection or M for list,
- P to set protocol, <CR> to exit: